React-hooks基本使用与调优

emmm,就是学习一哈hooks,跟着官方脚步走.下面会介绍hooks的API以及应用场景.

 

基础API

useState

使用useState设置默认值为0,每次点击button,使A的值+1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
export default () => {
// 其实useState返回的是一个数组,索引0给A设置默认值,索引1给setA赋值一个 可改变A的函数
const [A, setA] = useState(0)

const handleClickA = () => {
setA((count) => {
return count += 1
})
}

return(
<React.Fragment>
<button onClick={handleClickA}>Click A</button>
<span style={{color: 'red'}}>{A}</span>
</React.Fragment>
)
}

useEffect

使用useEffect模拟生命周期 componentDidMount, componentDidUpdate , componentWillUnmount

  • componentDidMount

    1
    2
    3
    useEffect(() => {
    console.log('this is componentDidMount')
    }, []) // 传入空数组 --> 没有依赖 --> 这个钩子只会渲染一次
  • componentDidUpdate

    1
    2
    3
    useEffect(() => {
    console.log('this is componentDidUpdate')
    }) // 不传入第二个参数,每次组件更新都会触发此钩子 --> 每次setState都会触发
  • componentWillUnmount

    1
    2
    3
    4
    5
    6
    useEffect(() => {
    console.log('this is componentDidMount')
    return () => {
    console.log('this is componentWillUnmount') // 在return内执行销毁前的操作
    }
    }, [])

使用useEffect实现属性监听

  • 1
    2
    3
    4
    5
    const [A, setA] = useState(0)

    useEffect(() => {
    console.log('点了AAA')
    }, [A]) // 只有当A的值改变才会触发console

useReducer

啥也不说,先让你看一段代码!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const initialState = {count: 0};

function reducer(state, action) { // 此FUNC可以单独封装,供多方调用
switch (action.type) {
case 'increment':
return {count: state.count + 1};
case 'decrement':
return {count: state.count - 1};
default:
throw new Error();
}
}

const [state, dispatch] = useReducer(reducer, initialState);
return (
<React.Fragment>
Count: {state.count}
<button onClick={() => dispatch({type: 'increment'})}>+</button>
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
</React.Fragment>
);

乍一看不就是mini版的redux么???

  • 写起来像redux,用起来像Mixins…

和Minxins有啥区别?和普通utils方法有啥区别?

  • 使用mixins是共享一个对象的数据空间的.而useReducer只提供数据处理的逻辑!!!保证每个数据空间独立,供多方调用.

  • 一个普通的utils函数并不能存储里的数据,而useReducer可以记住数据的状态!!!

useContext

可以实现子组件与祖先组件通信,兄弟组件通信,开发者可将provider挂载至任意共同父组件上! vue则是直接将provider挂载到根组件上.

我们使用useContext实现一个统计loading功能

jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// lodingContext.tsx

import React, { useState, createContext } from 'react';

const defaultValue = {
loadingCount: 0,
showLoading: () => {},
closeLoading: () => {}
}
export const LoadingContext = createContext(defaultValue);
console.log('LoadingContext====', LoadingContext)

export const LodingProvider = ({children}: any) => {

const showLoading = () => {
toggleLoading(prevState => {
return {
...prevState,
loadingCount: prevState.loadingCount + 1
}
})
}

const closeLoading = () => {
toggleLoading(prevState => {
return {
...prevState,
loadingCount:
prevState.loadingCount > 0 ? prevState.loadingCount - 1 : 0
}
})
}

const loadingState = {
loadingCount: 0,
showLoading,
closeLoading
}

const [loading, toggleLoading] = useState(loadingState)

return (
<LoadingContext.Provider value={loading}>
{children}
</LoadingContext.Provider>
)
}
jsx
1
2
3
4
5
6
7
8
9
10
// Home.tsx

import { LodingProvider } from '@/context/LoadingContext'

const layout =
<Layout className="home">
<LodingProvider>
...
</LodingProvider>
</Layout>
jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// welcome.tsx
import { LoadingContext } from '@/context/LoadingContext'

const contextData = useContext(LoadingContext)

useEffect(() => {
contextData.showLoading()
contextData.showLoading()
contextData.showLoading()
contextData.closeLoading()
}, [])

useEffect(() => {
console.log('loadingCount', contextData.loadingCount); // 2
})

性能优化

react16.8将shouldComponentUpdate来替换成了useMomo & useCallback

useMomo

useCallback

useMomo & useCallback

https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

https://zh-hans.reactjs.org/docs/hooks-reference.html

-------------本文结束 感谢您的阅读-------------